package com.XinYun.Library.modules.admin.common;

import com.XinYun.Library.utils.SqlUtils.DruidUtil;
import com.XinYun.Library.utils.SqlUtils.ResultSetHandlers.BeanHandler;
import com.XinYun.Library.utils.SqlUtils.ResultSetHandlers.BeanListHandler;
import com.XinYun.Library.utils.SqlUtils.ResultSetHandlers.ScalarHandler;
import com.XinYun.Library.utils.SqlUtils.SqlExecutor;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 共有操作
 * @param <T> 操作的表中数据类
 */
public class BasicDao<T> {
    /**
     * DML，操作行
     * @param sql sql修改语句
     * @param params 补充?参数
     * @return update 操作成功行数
     */
    public int dml(String sql,Object... params) throws RuntimeException {
        Connection connection = null;
        try {
            connection = DruidUtil.getConnection();
            int update = SqlExecutor.update(connection, sql, params);
            return update;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DruidUtil.close(connection);
        }
    }

    /**
     * DQL，查询多行
     * @param sql sql查询语句
     * @param objClass 结果表中元素类
     * @param params 补充?参数
     * @return 多个返回结果表中元素的集合
     * @throws RuntimeException
     */
    public List<T> dqlForBeanList(String sql, Class<T> objClass, Object... params) throws RuntimeException {
        Connection connection = null;
        try {
            connection = DruidUtil.getConnection();
            //返回多行数据，封装至集合，BeanListHandler中参数需要 通过操作的表中数据对象的类
            /*List<T> update = qr.query(connection, sql,new BeanListHandler<T>((Class<? extends T>) obj.getClass()),parm);*/
            //传入Class
            return (List<T>) SqlExecutor.select(connection, sql,new BeanListHandler<T>(objClass),params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DruidUtil.close(null,null,connection);
        }
    }

    /**
     * DQL，查询单行
     * @param sql sql查询语句
     * @param objClass 结果表中元素类
     * @param params 补充?参数
     * @return 多个返回结果表中元素的集合
     * @throws RuntimeException
     */
    public T dqlForBeanRow(String sql, Class<T> objClass, Object... params) throws RuntimeException {
        Connection connection = null;
        try {
            connection = DruidUtil.getConnection();
            //返回多行数据，封装至集合，BeanListHandler中参数需要 通过操作的表中数据对象的类
            /*List<T> update = qr.query(connection, sql,new BeanListHandler<T>((Class<? extends T>) obj.getClass()),parm);*/
            //传入Class
            return (T) SqlExecutor.select(connection, sql,new BeanHandler<T>(objClass),params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DruidUtil.close(null,null,connection);
        }
    }

    /**
     * DQL，查询单行
     * @param sql sql查询语句
     * @param objClass 结果表中元素类
     * @param params 补充?参数
     * @return 多个返回结果表中元素的集合
     * @throws RuntimeException
     */
    public List<T> dqlForScalar(String sql, Class<T> objClass, Object... params) throws RuntimeException {
        Connection connection = null;
        try {
            connection = DruidUtil.getConnection();
            //返回多行数据，封装至集合，BeanListHandler中参数需要 通过操作的表中数据对象的类
            /*List<T> update = qr.query(connection, sql,new BeanListHandler<T>((Class<? extends T>) obj.getClass()),parm);*/
            //传入Class
            return (List<T>) SqlExecutor.select(connection, sql,new ScalarHandler<T>(),params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DruidUtil.close(null,null,connection);
        }
    }
    /**
     * 查询结果分页化
     * @param sql 查询语句
     * @param pageSize  页大小
     * @param pageIndex 页索引
     */
    public List<T> pageBeanSelect(String sql, int pageSize, int pageIndex, Class<T> clazz){
        if(sql.endsWith(";")){
            int i = sql.lastIndexOf(";");
            sql = sql.substring(0,i);
        }
        //这里做一个分页查询
        sql = sql + " LIMIT ? OFFSET ?;";
        return dqlForBeanList(sql,clazz,pageSize, pageSize * (pageIndex - 1));
    }

    /**
     * 批量添加JavaBean
     * @param tableName
     * @param addObjs
     * @return 影响的行数
     * @param <T>
     * @throws IllegalAccessException
     */
    public <T> int addBean(String tableName,List<T> addObjs) throws IllegalAccessException {
        int row = 0;
        for (T addObj : addObjs) {
            String sql = null;
            Class clazz = addObj.getClass();
            Field[] fields = clazz.getDeclaredFields();
            //遍历字段获取值
            boolean isFirst = true;
            for (Field field : fields) {
                field.setAccessible(true);
                String value = null;
                //这里先简单处理，可以细化
                if(field.get(addObj) instanceof Integer){
                    value = String.valueOf(field.get(addObj));
                }else {
                    value = "'"+ field.get(addObj) +"'";
                }
                //这里拼接插入语句
                if(isFirst){
                    sql = "INSERT INTO "+tableName+" VALUES (" + value;
                    isFirst = false;
                }else {
                    sql += "," + value;
                }
            }
            sql += ");";
            row += dml(sql);
        }
        return row;
    }

}